﻿using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using CommandLineParser.Arguments;
using uTILLIty.Rave.Contract.Job;
using uTILLIty.Rave.Core.Manager;

namespace uTILLIty.Rave.Commandline
{
  /// <summary>
  /// Processes a <see cref="Job"/> file
  /// </summary>
	public class RunJobCommand : BaseCreateCommand
	{
		private readonly JobManager _jobManager;
		private readonly ConfigurationManager _configurationManager;

    /// <summary>
    /// Creates a default instance by DI/IoC
    /// </summary>
		public RunJobCommand(JobManager jobManager, ConfigurationManager configurationManager, CsvManager csvManager) : base(csvManager)
		{
			_jobManager = jobManager;
			_configurationManager = configurationManager;
		}

		/// <summary>
		/// The CSV file with the parameters (1st line containing the fieldnames)
		/// </summary>
		[FileArgument('j', "job", Optional = false, Description = "The XML-job file", FileMustExist = true,
			Example = "-j job_0728167331.xml")]
		public FileInfo JobFile;

		/// <summary>
		/// Wether to not really do anything, just log what would be done
		/// </summary>
		[ValueArgument(typeof(bool), 's', "simulate", Optional = true, Description = "Wether to not really do anything, just log what would be done")]
		public bool Simulate;

		/// <summary>
		/// The default path for relatively specified template-names within the job
		/// </summary>
		[DirectoryArgument('t', "template", DirectoryMustExist = true, Optional = true,
			Description = "The default path for relatively specified template-names within the job",
			Example = "-t \\server\templates")]
	  public DirectoryInfo TemplatesRoot;

    /// <summary>
    /// Invoked when the command is executed from the commandline
    /// </summary>
    protected override void OnExecute()
		{
			Job job;
			using (var stream = JobFile.OpenRead())
			{
				job = _jobManager.LoadJob(stream, JobFile.FullName);

				var mergeVariables = (job.MergeVariables ?? new MergeVariable[0]).ToList();
				if (!string.IsNullOrWhiteSpace(MergeVariables))
					ParseCommandlineMergeVariable(mergeVariables, MergeVariables, job.GetEncoding());

				job.MergeVariables = mergeVariables.ToArray();

				job.TraceSource.Listeners.Add(new ConsoleTraceListener());
				AdjustTemplatePath(job);
			}
			Console.WriteLine(Properties.Resources.JobStarted, job.JobId);
			var configuration = _configurationManager.LoadAndParse(job);
			_configurationManager.Apply(job, configuration, Simulate);
			Console.WriteLine(Properties.Resources.JobCompleted, job.JobId);
		}

		private void AdjustTemplatePath(Job job)
		{
			job.Template = Environment.ExpandEnvironmentVariables(job.Template);
			if (TemplatesRoot == null)
				return;
			if (Path.IsPathRooted(job.Template))
				return;
			job.Template = new FileInfo(Path.Combine(TemplatesRoot.FullName, job.Template)).FullName;
		}
	}
}